package main

import (
	"context"
	"fmt"
	"log"
	"net/http"
	"strconv"
	"strings"

	// "time"

	"grpc-jwt-yonghurenzheng/jwt_grpc/config" // 需要 JWTKey
	"grpc-jwt-yonghurenzheng/jwt_grpc/models"
	pb "grpc-jwt-yonghurenzheng/jwt_grpc/proto"

	"github.com/gin-gonic/gin"
	"github.com/golang-jwt/jwt/v4"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials/insecure"
)

// 全局 gRPC 客户端变量
var authClient pb.AuthServiceClient
var userClient pb.UserServiceClient

// === HTTP Handlers (负责将 HTTP 请求转换为 gRPC 调用) ===

// registerHandler 接收 HTTP 注册请求，并调用 Auth Service 的 gRPC 接口
func registerHandler(c *gin.Context) {
	var req pb.RegisterRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的请求数据: " + err.Error()})
		return
	}

	// 调用 gRPC 服务
	res, err := authClient.Register(context.Background(), &req)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "注册失败: " + err.Error()})
		return
	}

	c.JSON(http.StatusCreated, res)
}

// loginHandler 接收 HTTP 登录请求，并调用 Auth Service 的 gRPC 接口
func loginHandler(c *gin.Context) {
	var req pb.LoginRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的请求数据: " + err.Error()})
		return
	}

	// 调用 gRPC 服务
	res, err := authClient.Login(context.Background(), &req)
	if err != nil {
		c.JSON(http.StatusUnauthorized, gin.H{"error": "登录失败: " + err.Error()})
		return
	}

	c.JSON(http.StatusOK, res)
}

// profileHandler (正确版本)
func profileHandler(c *gin.Context) {
	// ① 从JWT中间件设置的上下文中获取 claims
	claimsAny, exists := c.Get("userClaims")
	if !exists {
		c.JSON(http.StatusUnauthorized, gin.H{"error": "未登录或Token无效"})
		return
	}
	// 进行类型断言，将 interface{} 转换为 *models.Claims
	claims, ok := claimsAny.(*models.Claims)
	if !ok {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "无法解析用户信息"})
		return
	}

	// ② 从URL路径参数中获取目标用户ID
	targetUserIDStr := c.Param("id")
	targetUserID, err := strconv.ParseInt(targetUserIDStr, 10, 64)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的用户ID"})
		return
	}

	// ③【核心修正】比较 Token 中的用户ID 和 路径中的目标ID
	if claims.UserID != targetUserID {
		c.JSON(http.StatusForbidden, gin.H{"error": "权限不足，禁止访问他人信息"})
		return
	}

	// 调用 gRPC 服务 (现在是安全的)
	res, err := userClient.GetUserProfile(context.Background(), &pb.GetUserProfileRequest{UserId: targetUserID})
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "获取用户信息失败: " + err.Error()})
		return
	}

	c.JSON(http.StatusOK, res)
}

// deleteUserHandler (正确版本)
func deleteUserHandler(c *gin.Context) {
	// ① 从JWT中间件获取 claims
	claimsAny, exists := c.Get("userClaims")
	if !exists {
		c.JSON(http.StatusUnauthorized, gin.H{"error": "未登录或Token无效"})
		return
	}
	claims, ok := claimsAny.(*models.Claims)
	// fmt.Printf("claim%v",claims)
	if !ok {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "无法解析用户信息"})
		return
	}

	// ② 从URL路径获取目标ID (假设路由为 /api/user/:id)
	targetUserIDStr := c.Param("id")
	targetUserID, err := strconv.ParseInt(targetUserIDStr, 10, 64)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的目标用户ID"})
		return
	}

	// ③【核心修正】进行授权检查
	if claims.UserID != targetUserID {
		c.JSON(http.StatusForbidden, gin.H{"error": "权限不足，无法删除他人账户"})
		return
	}

	// 调用 gRPC 服务
	res, err := userClient.DeleteUser(context.Background(), &pb.DeleteUserRequest{UserId: targetUserID})
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "删除用户失败: " + err.Error()})
		return
	}

	c.JSON(http.StatusOK, res)
}

// === JWT 中间件 ===

// jwtMiddleware 验证从客户端发来的 JWT
func jwtMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		authHeader := c.GetHeader("Authorization")
		if authHeader == "" {
			c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "请求头缺少 Authorization"})
			return
		}

		parts := strings.Split(authHeader, " ")
		if len(parts) != 2 || parts[0] != "Bearer" {
			c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "Authorization 请求头格式错误"})
			return
		}
		tokenString := parts[1]

		claims := &models.Claims{}
		token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) {
			return config.JWTKey, nil // 使用与 Auth Service 共享的密钥
		})

		if err != nil || !token.Valid {
			c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "无效的 Token"})
			return
		}

		// 验证通过，将用户ID存入 Gin 的上下文中，方便后续的 Handler 使用
		c.Set("userClaims", claims)

		// 继续处理请求
		c.Next()
	}
}

func main() {
	// 连接 Auth Service
	authConn, err := grpc.Dial("localhost:50051", grpc.WithTransportCredentials(insecure.NewCredentials()))
	if err != nil {
		log.Fatalf("无法连接 Auth Service: %v", err)
	}
	defer authConn.Close()
	authClient = pb.NewAuthServiceClient(authConn)

	// 连接 User Service
	userConn, err := grpc.Dial("localhost:50052", grpc.WithTransportCredentials(insecure.NewCredentials()))
	if err != nil {
		log.Fatalf("无法连接 User Service: %v", err)
	}
	defer userConn.Close()
	userClient = pb.NewUserServiceClient(userConn)

	// 设置 HTTP 路由
	r := gin.Default()

	public :=r.Group("jwt")
	{
		public.POST("/register", registerHandler)
		public.POST("/login", loginHandler)
	}

	private := r.Group("jwt")
	private.Use(jwtMiddleware())
	{
		private.GET("/profile/:id",profileHandler)
		private.DELETE("/delete_user/:id",deleteUserHandler)
	}
	port := "8080"
	fmt.Printf("🚀 Gin 服务启动于 http://localhost:%s\n", port)
	if err := r.Run(":" + port); err != nil {
		log.Fatal(err)
	}

}